using Godot;
using Godot.Collections;
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

public partial class Map : Area2D,ISavable,ILoadable
{
	[Export]
    protected MapEnemiesData _mapEnemiesData;
	[Export]
	public Vector2I CharacterAreaX;
	[Export]
	public Vector2I CharacterAreaY;
	public bool IsSafe = true;
	private Player _player;
	private Characters _mutant;
	private Camera2D _camera;
	private Node _charactersManager;
	private SaveLoadManager _saveLoadManager;
	public MapEnemiesData MapEnemiesData{get => _mapEnemiesData;}//获取对应的地图数据
	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
		var Game = GetNode<Game>("/root/Game");
		_player = Game.get_player();
		_camera = _player.GetNode<Camera2D>("Camera2D");
		_charactersManager = GetNode<Node>("CharactersManager");
		MessageManager messageManager = Game.get_message_manager();
		messageManager.EmitSignal("MapAdd",this);
		//GD.Print(this.MapEnemiesData.EnemiesList);
		update_characters_list();
		update_characters();//加载角色，脚本写的是enemies，懒得改了
		foreach(var child in _charactersManager.GetChildren())
		{
			Characters character = child as Characters;
			character.Initialize();
		}
		CheckCharactersSafe();
		//var scene = GD.Load<PackedScene>("res://entities/characters/enemies/mutant.tscn");//下三行为加载场景并添加到当前场景
		//var _mutant = scene.Instantiate();
		//this.AddChild(_mutant);
		
	}
	
	// Called every frame. 'delta' is the elapsed time since the previous frame.
	public virtual void Update(double delta)
	{
		update_characters_list();
		update_characters();//加载角色，脚本写的是enemies，懒得改了
		var children = _charactersManager.GetChildren();
		if(children.Count == 0)
		{return;}
		foreach(var child in children)
		{
			Characters character = child as Characters;
			if(character.CharacterData.health <= 0)
			{
				character.QueueFree();
				_mapEnemiesData.enemiesList.Remove(character.CharacterData.name);
			}
			character.Update(delta);
		}
		//GD.Print("角色数量：",_mapEnemiesData.enemiesList.Count);
	}

	public void Update_Player(Vector2 pos)
	{
		_player.GlobalPosition = pos;
		_camera.ResetSmoothing();
		GD.Print("切换完成，摄像机",_camera.Position);

	}
	public void update_characters()
	{
		foreach (string character in _mapEnemiesData.enemiesList)
		{
			string path = "res://entities/characters/enemies/" + character + "/" + character + ".tscn";
			//GD.Print(path);
			var scene = GD.Load<PackedScene>(path);
			if (scene != null)
			{
				Characters new_character = (Characters)scene.Instantiate();
				if(CheckCharacter(new_character))
				{continue;}
				_charactersManager.AddChild(new_character);
				Random random = new Random();
				var x = random.Next(-224,224);
				Vector2I pos = new Vector2I(x, random.Next(112-Math.Abs(x)/2,224-Math.Abs(x)/2));
				try
				{
					pos = _mapEnemiesData.characterBirthPosition[character];
				}
				catch (Exception e)
				{
					GD.Print("没有相关角色。错误信息",e);
				}
				finally
				{
					GD.Print(pos);
				}
				//GD.Print(character);
				new_character.GlobalPosition = pos + this.GlobalPosition;
			}
			else
			{
				GD.Print("无该角色");
				this.MapEnemiesData.enemiesList.Remove(character);
			}
		}
	}

	public bool CheckCharacter(Characters character)
	{
		bool result = false;
		foreach (Characters child in _charactersManager.GetChildren())
		{
			if(child.Name == character.Name)
			{
				return true;
			}
		}
		return result;
	}

	public virtual void update_characters_list()
	{}

	public void CheckCharactersSafe()
	{
		var children = _charactersManager.GetChildren();
		foreach (var child in children)
		{
			Characters chara = child as Characters;
			if(!chara.safe)
			{this.IsSafe = false; break;}
		}
	}

	public void SaveMapData()
	{}

	public bool InitializeByLoadData()
    {
        if(_saveLoadManager.LoadData ==null ||_saveLoadManager.LoadData.Count == 0)
        {
            return false;
        }
        if(!_saveLoadManager.LoadData.ContainsKey("map"))
        {return false;}

        var player = _saveLoadManager.LoadData["map"].AsGodotDictionary<string ,Variant>();

        InitializeByCharacterData(player);
        

        return false;
    }

    public Godot.Collections.Dictionary<string, Variant> GetDataForSave()
    {
		Variant enemylist = Variant.From(this.MapEnemiesData.enemiesList);
        return new Godot.Collections.Dictionary<string, Variant>
        {
            {"name", this.MapEnemiesData.name},
			{"enemiesList", enemylist}
        };
    }

    public Godot.Collections.Dictionary<string, Variant> GetDataForLoad()
    {
        throw new NotImplementedException();
    }

	protected void InitializeByCharacterData(Dictionary<string , Variant> mapLoadData)
    {
        MapEnemiesData.name = mapLoadData["name"].AsString();
		MapEnemiesData.enemiesList = mapLoadData["enemiesList"].AsGodotArray<string>();
    }

}
	
